import curses
import random
import time

# 游戏配置参数
WIDTH = 20  # 窗口宽度
HEIGHT = 20  # 窗口高度
SNAKE_SPEED = 0.1  # 蛇移动速度（秒）
SCORE_INCREMENT = 10  # 每吃一个食物加分

# 游戏状态常量
GAME_RUNNING = 1
GAME_PAUSED = 2
GAME_OVER = 3

# 方向常量
DIRECTIONS = {
    'UP': curses.KEY_UP,
    'DOWN': curses.KEY_DOWN,
    'LEFT': curses.KEY_LEFT,
    'RIGHT': curses.KEY_RIGHT
}

# 游戏窗口初始化
def init_game_window():
    # 初始化 curses 环境
    screen = curses.initscr()
    curses.curs_set(0)  # 隐藏光标
    screen.clear()
    screen.keypad(True)
    curses.noecho()
    curses.cbreak()
    screen.timeout(100)  # 控制刷新频率

    # 设置窗口大小
    height, width = screen.getmaxyx()
    if height < HEIGHT or width < WIDTH:
        screen.clear()
        screen.addstr("窗口太小，无法运行游戏！请调整终端大小。\n")
        screen.getch()
        curses.endwin()
        exit()

    # 创建游戏窗口
    win = curses.newwin(HEIGHT, WIDTH, 0, 0)
    win.keypad(True)
    win.timeout(100)
    win.border(0, 0, 0, 0, 0, 0, 0, 0)
    win.refresh()
    return screen, win

# 初始化蛇
def init_snake():
    snake = [(WIDTH // 2, HEIGHT // 2)]
    return snake

# 初始化食物
def init_food(snake):
    while True:
        food = (
            random.randint(1, WIDTH - 2),
            random.randint(1, HEIGHT - 2)
        )
        if food not in snake:
            return food

# 绘制游戏界面
def draw_game(win, snake, food, score):
    win.clear()
    win.border(0, 0, 0, 0, 0, 0, 0, 0)
    win.addstr(0, 2, f"得分: {score}")
    win.addstr(0, 2, "得分: {score}".format(score=score))

    # 绘制蛇
    for segment in snake:
        win.addstr(segment[1], segment[0], '#')

    # 绘制食物
    win.addstr(food[1], food[0], '*')

    win.refresh()

# 检查碰撞
def check_collision(snake, food, score):
    head = snake[0]
    # 撞墙
    if head[0] in (0, WIDTH - 1) or head[1] in (0, HEIGHT - 1):
        return GAME_OVER, score

    # 撞到自身
    if head in snake[1:]:
        return GAME_OVER, score

    # 吃到食物
    if head == food:
        score += SCORE_INCREMENT
        return GAME_RUNNING, score

    return GAME_RUNNING, score

# 主游戏循环
def game_loop(win, screen):
    snake = init_snake()
    food = init_food(snake)
    score = 0
    direction = 'RIGHT'
    game_state = GAME_RUNNING

    while True:
        win.clear()
        win.border(0, 0, 0, 0, 0, 0, 0, 0)
        win.addstr(0, 2, f"得分: {score}")
        win.addstr(0, 2, "得分: {score}".format(score=score))

        # 绘制蛇
        for segment in snake:
            win.addstr(segment[1], segment[0], '#')

        # 绘制食物
        win.addstr(food[1], food[0], '*')

        win.refresh()

        if game_state == GAME_OVER:
            win.addstr(HEIGHT // 2, WIDTH // 2 - 5, "游戏结束！")
            win.addstr(HEIGHT // 2 + 1, WIDTH // 2 - 5, f"最终得分: {score}")
            win.refresh()
            screen.getch()
            break

        if game_state == GAME_PAUSED:
            screen.getch()
            continue

        # 获取用户输入
        key = screen.getch()
        if key == curses.KEY_UP and direction != 'DOWN':
            direction = 'UP'
        elif key == curses.KEY_DOWN and direction != 'UP':
            direction = 'DOWN'
        elif key == curses.KEY_LEFT and direction != 'RIGHT':
            direction = 'LEFT'
        elif key == curses.KEY_RIGHT and direction != 'LEFT':
            direction = 'RIGHT'
        elif key == ord('p'):
            game_state = GAME_PAUSED
        elif key == ord('q'):
            break

        # 移动蛇
        head = snake[0]
        if direction == 'UP':
            new_head = (head[0], head[1] - 1)
        elif direction == 'DOWN':
            new_head = (head[0], head[1] + 1)
        elif direction == 'LEFT':
            new_head = (head[0] - 1, head[1])
        else:  # RIGHT
            new_head = (head[0] + 1, head[1])

        snake.insert(0, new_head)

        # 检查碰撞
        game_state, score = check_collision(snake, food, score)

        # 如果没有吃食物，移除尾部
        if game_state == GAME_RUNNING and snake[0] != food:
            snake.pop()

        # 如果吃到了食物，生成新的食物
        if snake[0] == food:
            food = init_food(snake)

        time.sleep(SNAKE_SPEED)

    curses.endwin()

if __name__ == "__main__":
    screen, win = init_game_window()
    game_loop(win, screen)
    
